package com.linkstec.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;

import org.apache.commons.lang.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;



public class HttpClientUtil {

	private static final Logger logger = LogManager.getLogger();
	public static final String MIME_JSON = "application/json";
	public static final String MIME_TEXT = "text/plain";
	public static final String MIME_HTML = "text/html";
	public static int SOCKET_TIMEOUT = 30000;
	public static int MAX_CONN = 200;
	private static CloseableHttpClient httpclient = null;
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private static ResponseHandler<String> responseHandler = new ResponseHandler() {
		@Override
        public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
			int status = response.getStatusLine().getStatusCode();
			if ((status >= 200) && (status < 300)) {
				HttpEntity entity = response.getEntity();
				return ((entity != null) ? EntityUtils.toString(entity) : null);
			}
			throw new ClientProtocolException("Unexpected response status: " + status);
		}
	};

	static {
		RequestConfig defaultRequestConfig = RequestConfig.custom().setSocketTimeout(SOCKET_TIMEOUT)
				.setConnectTimeout(5000).setConnectionRequestTimeout(5000).build();
		try {
			SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(new TrustStrategy() {
				@Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
					return true;
				}
			}).build();

			SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1","TLSv1.2" }, null,
					new HostnameVerifier() {
						@Override
                        public boolean verify(String arg0, SSLSession arg1) {
							return true;
						}
					});
			@SuppressWarnings("rawtypes")
			Registry socketFactoryRegistry = RegistryBuilder.create()
					.register("http", PlainConnectionSocketFactory.INSTANCE).register("https", sslsf).build();

			@SuppressWarnings("unchecked")
			PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
			ConnectionConfig connectionConfig = ConnectionConfig.custom().setCharset(Consts.UTF_8).build();
			cm.setDefaultConnectionConfig(connectionConfig);
			cm.setMaxTotal(MAX_CONN);
			cm.setDefaultMaxPerRoute(MAX_CONN);

			httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).setConnectionManager(cm)
					.build();
		} catch (Exception e) {
		}
	}

	public static void closeHttpClient() {
		if (httpclient == null)
			return;
		try {
			httpclient.close();
		} catch (IOException e) {
		}
	}

	public static String httpGet(String url) throws ConnectException {
		HttpGet httpget = new HttpGet(url);

		String responseBody = null;
		try {
			responseBody = httpclient.execute(httpget, responseHandler);
		} catch (ConnectException e) {
			throw e;
		} catch (Exception e) {
		}

		return responseBody;
	}

	public static String post(HttpPost httpPost) throws ClientProtocolException, IOException {
        String responseBody = null;
        responseBody = httpclient.execute(httpPost, responseHandler);
        logger.debug(responseBody);
        return responseBody;
    }
	public static String httpPost(String url, String body) throws ConnectException {
		return httpPost(url, body, "text/plain");
	}

	public static String httpPost(String url, String body, String mimeType) throws ConnectException {
		HttpPost httppost = new HttpPost(url);
		if (StringUtils.isNotBlank(body)) {
			httppost.setEntity(new StringEntity(body, ContentType.create(mimeType, "UTF-8")));
		}

		String responseBody = null;
		try {
			responseBody = httpclient.execute(httppost, responseHandler);
		} catch (ConnectException e) {
			throw e;
		} catch (Exception e) {
		}
		return responseBody;
	}

	public static String httpPostByNameValue(String url, List<NameValuePair> formparams) throws ConnectException {
		HttpPost httppost = new HttpPost(url);
		if (formparams != null && formparams.size() > 0) {
			httppost.setEntity(new UrlEncodedFormEntity(formparams, Consts.UTF_8));
		}

		String responseBody = null;
		try {
			responseBody = httpclient.execute(httppost, responseHandler);
		} catch (ConnectException e) {
			throw e;
		} catch (Exception e) {
		}
		return responseBody;
	}

	/**
	 *
	 * @param url
	 * @param json
	 * @return
	 */
	public static String HttpPostWithJson(String url, String json) throws Exception{
		String returnValue = "这是默认返回值，接口调用失败";
		CloseableHttpClient cookiehttpclient = null;
		try{

	        HttpPost httpPost = new HttpPost(url);
	        StringEntity requestEntity = new StringEntity(json,"UTF-8");
	        requestEntity.setContentEncoding("UTF-8");
	        httpPost.setHeader("Content-type", "application/json;charset=UTF-8");
	        httpPost.setEntity(requestEntity);
//	        cookiehttpclient = getHttpClients("admin","71e8ad78f91236792c16bb427b53022b");
	        cookiehttpclient = getHttpClients("admin",FlowjobConfigUtil.getProperty("xjobflowPassword"));
	       returnValue = cookiehttpclient.execute(httpPost,responseHandler); //调接口获取返回值时，必须用此方法

		}
		 catch(Exception e)
		{
			 logger.info("", e);
		}

		finally {
			try {
				cookiehttpclient.close();
			} catch (IOException e) {
				logger.info("", e);
			}
	    }
	     return returnValue;
	}

	/**
	 *
	 * @param url
	 * @param json
	 * @return
	 */
	public static String httpPostWithJson(String url, String json) throws Exception{
		String returnValue = "这是默认返回值，接口调用失败";
		CloseableHttpClient cookiehttpclient = null;
		try{

			HttpPost httpPost = new HttpPost(url);
			StringEntity requestEntity = new StringEntity(json,"UTF-8");
			requestEntity.setContentEncoding("UTF-8");
			httpPost.setHeader("Content-type", "application/json;charset=UTF-8");
			httpPost.setEntity(requestEntity);
			cookiehttpclient = getHttpClients("admin",FlowjobConfigUtil.getProperty("xjobflowPassword"));
			returnValue = cookiehttpclient.execute(httpPost,responseHandler); //调接口获取返回值时，必须用此方法

		}
		catch(Exception e) {
			logger.info("", e);
		}

		finally {
			try {
				cookiehttpclient.close();
			} catch (IOException e) {
				logger.info("", e);
			}
		}
		return returnValue;
	}
	/**
	 *
	 * @param url
	 * @param json
	 * @return
	 */
	public static String HttpGetWithJson(String url, String json) throws Exception{
		String returnValue = "这是默认返回值，接口调用失败";
		CloseableHttpClient cookiehttpclient = null;
		try{

			HttpGet httpget = new HttpGet(url);
//	        cookiehttpclient = getHttpClients("admin","71e8ad78f91236792c16bb427b53022b");
			cookiehttpclient = getHttpClients("admin",FlowjobConfigUtil.getProperty("xjobflowPassword"));
			returnValue = cookiehttpclient.execute(httpget,responseHandler); //调接口获取返回值时，必须用此方法

		}
		catch(Exception e)
		{
			logger.info("", e);
		}

		finally {
			try {
				cookiehttpclient.close();
			} catch (IOException e) {
				logger.info("", e);
			}
		}
		return returnValue;
	}
	public static CloseableHttpClient getHttpClients(String username, String password) {
//        HttpPost httppost = new HttpPost("http://192.168.2.174:8085/lzdata-flowjob-admin/sys/login");//httppost
        HttpPost httppost = new HttpPost(FlowjobConfigUtil.getProperty("xjobflowUrl") + "sys/login");//httppost
        CloseableHttpClient httpClient = null;
        try {
            List<NameValuePair> para = new ArrayList<NameValuePair>();
            para.add(new BasicNameValuePair("password", password));
            para.add(new BasicNameValuePair("username", username));//构造表单

    		Map<String, Object> data = new HashMap<String, Object>();
    		data.put("password", password);
    		data.put("username", username);
    		String jsonData = JSON.toJSONString(data);
    		StringEntity requestEntity = new StringEntity(jsonData,"UTF-8");
            httppost.setHeader(
                    "User-Agent",
                    "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36");
            httppost.setHeader("Content-type", "application/json;charset=UTF-8");
//            httppost.setEntity(new UrlEncodedFormEntity(para, "utf-8"));//设置请求体
            httppost.setEntity(requestEntity);//设置请求体
            BasicCookieStore cookieStore = new BasicCookieStore();//建立一个CookieStore
            httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();//建立带cookie的httpClient
//            int statuts_codes = httpClient.execute(httppost).getStatusLine().getStatusCode();//发送请求，发送成功后cookie将存在于cookieStore中
            CloseableHttpResponse chr = httpClient.execute(httppost);
            int statuts_codes = chr.getStatusLine().getStatusCode();
            if (statuts_codes == HttpStatus.SC_OK) {//请求成功
                List<Cookie> cookies = cookieStore.getCookies();//遍历获取需要的值
                for (int i = 0; i < cookies.size(); i++) {//获取JSESSIONID
                    if (cookies.get(i).getName().equals("LzdataSessionID")) {
                    }
                }

            } else {//请求失败

            }
        } catch (UnsupportedEncodingException ex) {

        } catch (IOException ex) {

        } finally {
            httppost.releaseConnection();//释放资源
        }
        return httpClient;
    }
}
